package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/event"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

const (
	SLOW_QUERY_THRESHOLD = 0 // 1秒
)

func newSlowQueryMonitor() *event.CommandMonitor {
	return &event.CommandMonitor{
		Started: func(ctx context.Context, evt *event.CommandStartedEvent) {
			// 可选：记录开始时间（但通常用 Ended 的 Duration 更准）
			// 实际耗时由 Ended 事件提供
			log.Printf("%+v\n", evt)
		},
		Succeeded: func(ctx context.Context, evt *event.CommandSucceededEvent) {
			if evt.Duration >= SLOW_QUERY_THRESHOLD {
				log.Printf(
					"[WARN] Slow MongoDB query: db=%s, collection=%+v,  duration=%v, evt=%+v",
					evt.DatabaseName,
					evt.Reply,
					// redactCommand(bson.Raw(evt.CommandName)), // 可选：脱敏
					evt.Duration,
					evt,
				)
			}
		},
		Failed: func(ctx context.Context, evt *event.CommandFailedEvent) {
			if evt.Duration >= SLOW_QUERY_THRESHOLD {
				log.Printf(
					"[WARN] Slow MongoDB query (failed): db=%s, command=%s, duration=%v, error=%v | evt=%+v",
					evt.DatabaseName,
					evt.CommandName,
					evt.Duration,
					evt.Failure,
					evt,
				)
			}
		},
	}
}

func redactCommand(cmd bson.Raw) string {
	var m map[string]interface{}
	if err := bson.Unmarshal(cmd, &m); err != nil {
		return "{unmarshal_error}"
	}

	// 移除敏感字段，如密码、token 等（根据你的业务调整）
	delete(m, "pwd")
	delete(m, "password")
	delete(m, "credentials")

	// 限制长度，避免日志爆炸
	b, _ := json.Marshal(m)
	s := string(b)
	if len(s) > 500 {
		s = s[:500] + "..."
	}
	return s
}

type MatchInfo struct {
	MatchId int64 `bson:"match_id"`
	Sid     int32 `bson:"sid"`
}

func main() {
	// connect to MongoDB
	opts := options.Client()
	// opts.Monitor = otelmongo.NewMonitor()
	// opts.Monitor.Started = func(ctx context.Context, evt *event.CommandStartedEvent) {
	// 	fmt.Printf("mongo cmd started, event: %+v \n", evt)
	// }
	opts.Monitor = newSlowQueryMonitor()
	opts.ApplyURI("mongodb://admin:1q2w3e4r@localhost:27017/")
	client, err := mongo.Connect(context.Background(), opts)
	if err != nil {
		panic(err)
	}
	db := client.Database("aggregator_server")
	inventory := db.Collection("match_info")

	// _, err = inventory.InsertOne(context.Background(), bson.D{
	// 	{Key: "item", Value: "canvas"},
	// 	{Key: "qty", Value: 100},
	// 	{Key: "attributes", Value: bson.A{"cotton"}},
	// 	{Key: "size", Value: bson.D{
	// 		{Key: "h", Value: 28},
	// 		{Key: "w", Value: 35.5},
	// 		{Key: "uom", Value: "cm"},
	// 	}},
	// })
	// option := options.Find().SetSort(bson.D{{"create_time", 1}, {"_id", 1}})

	var mt MatchInfo

	filter := map[string]any{
		"match_id": 28225821,
	}
	for range 10 {

	}

	err = inventory.FindOne(context.Background(), filter).Decode(&mt)
	fmt.Printf("%+v", mt)
	if err != nil {
		panic(err)
	}

}
